import { FormInstance } from 'antd';
import debounce from 'lodash/debounce';
import { makeAutoObservable, runInAction } from 'mobx';
import userApi from '../../api/userApi';
import { dayjs2Date, date2Dayjs } from '../../utils/dateUtil';

const defaultNewPassword: string = 'abc123';

export default class User {

  loading: boolean;
  detailLoading: boolean;
  saving: boolean;
  data: any[];
  record: any;
  passwordStatus: string;
  current: number;
  pageSize: number;
  total: number;
  conditions: object;

  constructor() {
    this.loading = false;
    this.detailLoading = false;
    this.saving = false;
    this.data = [];
    this.record = null;
    this.passwordStatus = 'unset';
    this.current = 0;
    this.pageSize = 10;
    this.total = 0;
    this.conditions = this.getDefaultConditions();
    makeAutoObservable(this);
  }

  async fetchData(keyword: string, active: string, locked: string, superuser: string, type: string, pageNumber: number) {
    if (this.loading) {
      return;
    }

    runInAction(() => {
      this.loading = true;
    });
    const res: any = await userApi.query(keyword, active, locked, superuser, type, pageNumber, this.pageSize);
    const list: any[] = res.data?.list || [];
    this.selectRecord(null);
    runInAction(() => {
      this.data = list;
      this.current = res.data?.current || 0;
      this.total = res.data?.total || 0;
      this.loading = false;
      this.conditions = {
        keyword,
        active,
        locked,
        superuser,
        type,
        pageNumber
      };
    });
  }

  async fetchDetail() {
    if (this.detailLoading) {
      return;
    }

    runInAction(() => {
      this.detailLoading = true;
    });
    const res: any = await userApi.find(this.record?.id);
    runInAction(() => {
      this.record = res.data;
      this.detailLoading = false;
    });
  }

  saveData(values: any) {
    this.setSaving(true);
    const id: string = this.record ? this.record.id : null;
    const data: any = {
      id,
      ...values
    };
    data.effectiveDate = dayjs2Date(data.effectiveDateValue);
    data.terminateDate = dayjs2Date(data.terminateDateValue);
    data.passwordTerminateDate = dayjs2Date(data.passwordTerminateDateValue);
    if (this.passwordStatus !== 'unset') {
      data.password = data.newPassword;
    } else {
      data.password = null;
    }
    return userApi.save(data);
  }

  deleteData() {
    return userApi.delete(this.record ? this.record.id : '<empty>');
  }

  addRecord(record: any) {
    runInAction(() => {
      let data = this.data.concat();
      let total = this.total + 1;
      data.unshift(record);
      data.splice(this.pageSize);
      this.selectRecord(null);
      this.data = data;
      this.total = total;
    });
  }

  getEditRecord() {
    let currentRecord: any = null;
    if (this.record) {
      currentRecord = { ...this.record };
      currentRecord.newPassword = defaultNewPassword;
      currentRecord.passwordChanged = false;
    } else {
      currentRecord = {
        username: '',
        password: '',
        newPassword: '',
        passwordChanged: false,
        name: '',
        company: '',
        title: '',
        email: '',
        mobile: '',
        telephone: '',
        effectiveDate: null,
        terminateDate: null,
        needChangePassword: true,
        passwordTerminateDate: null,
        lastLoginTime: null,
        lastLoginIp: null,
        avatar: null,
        remark: '',
        active: true,
        locked: false,
        superuser: false,
        type: ''
      }
    }
    currentRecord.effectiveDateValue = date2Dayjs(currentRecord.effectiveDate);
    currentRecord.terminateDateValue = date2Dayjs(currentRecord.terminateDate);
    currentRecord.passwordTerminateDateValue = date2Dayjs(currentRecord.passwordTerminateDate);
    return currentRecord;
  }

  selectRecord(record: any) {
    runInAction(() => {
      this.record = record
    });
  }

  setPasswordStatus(passwordStatus: string, form?: FormInstance) {
    runInAction(() => {
      this.passwordStatus = passwordStatus;
    });
    if (form) {
      if (passwordStatus === 'changed') {
        form.setFieldValue('newPassword', '');
      } else if (passwordStatus === 'unset') {
        form.setFieldValue('newPassword', defaultNewPassword);
      }
      form.validateFields(['newPassword']);
    }
  }

  setPageSize(pageSize: number) {
    runInAction(() => {
      this.pageSize = pageSize;
    });
  }

  setSaving(saving: boolean) {
    runInAction(() => {
      this.saving = saving;
    });
  }

  getDefaultConditions() {
    return {
      keyword: '',
      active: '',
      locked: '',
      superuser: '',
      type: '',
      pageNumber: 0
    };
  }

  resetConditions(form: FormInstance<any>) {
    runInAction(() => {
      this.conditions = this.getDefaultConditions();
      debounce(() => form.resetFields(), 50)();
    });
  }

  setConditions(conditions: any) {
    runInAction(() => {
      this.conditions = conditions;
    });
  }

};
